#ifndef GLWIDGET_H
#define GLWIDGET_H

// 头文件 GLWidget.h
#include <QOpenGLWidget>
#include <QOpenGLFunctions_4_5_Core>
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
#include <QPainter>

class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions_4_5_Core {
public:
    explicit GLWidget(QWidget *parent = nullptr): QOpenGLWidget(parent){
    };
    ~GLWidget(){
        makeCurrent();
          delete m_texture;
          delete m_texture_text;
          glDeleteBuffers(2, VBO);
          glDeleteBuffers(2, EBO);
          glDeleteVertexArrays(2, VAO);
          doneCurrent();
    };

    //设置矩形框颜色，默认：红色，50%透明度
    void setRectColor(QVector4D color = QVector4D(1.0f, 0.0f, 0.0f, 0.5f)) {
        m_rectColor = color;
    }

    void setRect(QList<QRectF> rects){
        makeCurrent();
        m_rects = rects;
        updateRectBuffer();

        update();
    }

protected:
    void initializeGL() override;
    void paintGL() override;
    void resizeGL(int w, int h) override;


    QImage createTextTexture(const QString& text, int width, int height);
    void updateRectBuffer();

private:
    QOpenGLShaderProgram m_program;
    QOpenGLShaderProgram m_rectProgram;   // 矩形框渲染着色器
    QOpenGLTexture *m_texture;
    QOpenGLTexture *m_texture_text;
    GLuint VAO[2], VBO[2], EBO[2];
    GLuint m_rectVBO;
    QMatrix4x4 m_modelMatrix;
    QList<QRectF> m_rects;                // 当前矩形框列表
    QVector4D m_rectColor;                // 矩形框颜色
};

QImage GLWidget::createTextTexture(const QString& text, int width, int height) {
    QImage image(width, height, QImage::Format_ARGB32);
    image.fill(Qt::transparent);

    QPainter painter(&image);
    painter.setPen(Qt::white);
    painter.setFont(QFont("Arial", 24));
    painter.drawText(image.rect(), Qt::AlignCenter, text);
    painter.end();

    // OpenGL 纹理坐标系原点在左下角，需垂直翻转图像
    return image.mirrored(false, true);
}


// 实现文件 GLWidget.cpp
void GLWidget::initializeGL() {
    initializeOpenGLFunctions();
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);

    // 编译着色器
    m_program.addShaderFromSourceCode(QOpenGLShader::Vertex,
        "#version 450 core\n"
        "layout (location=0) in vec3 aPos;\n"
        "layout (location=1) in vec2 aTexCoord;\n"
        "out vec2 TexCoord;\n"
        "uniform mat4 model;\n"
        "void main() {\n"
        "  gl_Position = model * vec4(aPos, 1.0);\n"
        "  TexCoord = aTexCoord;\n"
        "}");

    m_program.addShaderFromSourceCode(QOpenGLShader::Fragment,
        "#version 450 core\n"
        "in vec2 TexCoord;\n"
         "in float vPosY;\n"
        "out vec4 FragColor;\n"
        "uniform sampler2D texture1;\n"
        "void main() {\n"
            "  FragColor = texture(texture1, TexCoord);\n"
        "}");
   bool b = m_program.link();
   if(!b){
    qDebug() << "Shader Error:" << m_program.log();
   }

    // 顶点数据（包含位置和纹理坐标）
    float vertices1[] = {
        // positions       // texture coords
        -0.8f, -0.8f, 0.0f, 0.0f, 0.0f,
         0.0f, -0.8f, 0.0f, 1.0f, 0.0f,
         -0.8f,  0.8f, 0.0f, 0.0f, 1.0f,
         0.0f,  0.8f, 0.0f, 1.0f, 1.0f
    };

    float vertices2[] = {
        // positions       // texture coords
         0.0f, -0.8f, 0.0f, 0.0f, 0.0f,
         0.8f, -0.8f, 0.0f, 1.0f, 0.0f,
         0.0f,  0.8f, 0.0f, 0.0f, 1.0f,
         0.8f,  0.8f, 0.0f, 1.0f, 1.0f
    };

    // 创建VBO和VAO
    glGenVertexArrays(2, VAO);
    glGenBuffers(2, VBO);
    glGenBuffers(2, EBO); // 可选（用于索引绘制）

    //配置VAO
    glBindVertexArray(VAO[0]);
    glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW);

    // 将索引数据复制到 EBO（如果有）
    unsigned int indices1[] = {0, 1, 2,
                              1, 3, 2};
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[0]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices1), indices1, GL_STATIC_DRAW);

    // 设置顶点属性指针
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void*)(3*sizeof(float)));
    glEnableVertexAttribArray(1);

    //配置VAO
    glBindVertexArray(VAO[1]);
    glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);

    // 将索引数据复制到 EBO（如果有）
    unsigned int indices2[] = {0, 1, 2,
                              1, 3, 2};
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[0]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices2), indices2, GL_STATIC_DRAW);

    // 设置顶点属性指针
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void*)(3*sizeof(float)));
    glEnableVertexAttribArray(1);

    // 解绑
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    // 加载纹理
    m_texture = new QOpenGLTexture(QImage(":/textures/wood.jpg").mirrored());
    m_texture->setWrapMode(QOpenGLTexture::Repeat);
    m_texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);

    QImage textImage = createTextTexture("Hello OpenGL!", 256, 32);
    m_texture_text = new QOpenGLTexture(textImage);
    m_texture_text->setWrapMode(QOpenGLTexture::Repeat);
    m_texture_text->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);

    m_rectProgram.addShaderFromSourceCode(QOpenGLShader::Vertex,
                    "layout (location=0) in vec2 position;\n"
                    "void main() {"
                    "    gl_Position = vec4(position, 0.0, 1.0);"
                    "}");
    m_rectProgram.addShaderFromSourceCode(QOpenGLShader::Fragment,
                    "uniform vec4 color;"
                    "void main() {"
                    "    gl_FragColor = color;"
                    "}");
   m_rectProgram.link();

   // 初始化矩形顶点缓冲
   glGenBuffers(1, &m_rectVBO);
}

void GLWidget::updateRectBuffer() {
    if (m_rects.isEmpty()) return;

    // 将 QRectF 转换为归一化坐标（-1 到 1）
    qDebug()<<width()<<height();
    QVector<float> vertices;
    for (const QRectF &rect : m_rects) {
        float x1 = (rect.x() / width()) * 2 - 1;
        float y1 = 1 - (rect.y() / height()) * 2;
        float x2 = ((rect.x() + rect.width()) / width()) * 2 - 1;
        float y2 = 1 - ((rect.y() + rect.height()) / height()) * 2;

        // 每个矩形由 4 条线段组成（每条线段 2 个点）
        vertices << x1 << y1 << x2 << y1;  // 上边
        vertices << x2 << y1 << x2 << y2;  // 右边
        vertices << x2 << y2 << x1 << y2;  // 下边
        vertices << x1 << y2 << x1 << y1;  // 左边
    }

    // 更新 VBO
    glBindBuffer(GL_ARRAY_BUFFER, m_rectVBO);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float),
                 vertices.constData(), GL_DYNAMIC_DRAW);

}

void GLWidget::paintGL() {
    glClear(GL_COLOR_BUFFER_BIT);

    m_program.bind();

    // 设置模型矩阵（平移变换）
    m_modelMatrix.setToIdentity();
    m_modelMatrix.translate(0.0f, 0.0f, 0.0f);
    m_program.setUniformValue("model", m_modelMatrix);

    // 绑定纹理
    m_texture->bind(0);
    m_program.setUniformValue("texture1", 0);
    // 绘制矩形
    glBindVertexArray(VAO[0]);
    //glDrawArrays(GL_TRIANGLE_STRIP,0,4);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

    // 绑定纹理
    m_texture_text->bind(0);
    m_program.setUniformValue("texture1", 0);
    // 绘制矩形
    glBindVertexArray(VAO[1]);
    //glDrawArrays(GL_TRIANGLE_STRIP,0,4);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

    // 解绑VAO
    glBindVertexArray(0);
    m_program.release();


    // 渲染动态矩形框
   if (!m_rects.isEmpty()) {
           m_rectProgram.bind();
            glBindBuffer(GL_ARRAY_BUFFER, m_rectVBO);

            // 设置颜色
            m_rectProgram.setUniformValue("color", m_rectColor);

            // 设置顶点属性
            glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
            glEnableVertexAttribArray(0);

            // 绘制线段（每个矩形 4 条边，每条边 2 个顶点）
            glLineWidth(2.0f);
            glDrawArrays(GL_LINES, 0, m_rects.size() * 8); // 4边 * 2点 = 8点/矩形

            m_rectProgram.release();
    }
}

void GLWidget::resizeGL(int w, int h) {
    glViewport(0, 0, w, h);
}

#endif // GLWIDGET_H
